/****************************************************
*	OSMF Edge Media Player version 1.2.0
* 
*	Author: Emanuele Manco
* 	E-Mail: hello@flashedge.net
*	Web: http://activeden.net/user/flashedge
*  
*****************************************************/

package net.flashedge.core 
{
	import com.greensock.events.LoaderEvent;
	import com.greensock.loading.ImageLoader;
	import com.greensock.loading.LoaderMax;
	import flash.events.MouseEvent;
	
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.filters.GlowFilter;
	import flash.text.AntiAliasType;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	import net.flashedge.utils.Grid;	// utility class to create playlist grid
	
	import com.greensock.*;
	import com.greensock.easing.*;
	

	public class Playlist extends Sprite
	{
		public var c:Number = 1;	// column
		public var r:Number = 1;	// row
		
		public var primary:primaryFont = new primaryFont();
		public var secondary:secondaryFont = new secondaryFont();
		
		public var nextBtn:arrowBtn = new arrowBtn();
		public var prevBtn:arrowBtn = new arrowBtn();
		
		public var plMask:Sprite = new Sprite();
		
		public var queue:LoaderMax;								// main queue loader
		public var main:Sprite = new Sprite();
		public var entries:Sprite = new Sprite();
		
		public var enabled:Boolean = true;
		public var pl:Array;
		
		public var setup;
		
		public var plWidth:Number;
		public var plHeight:Number;
		public var cols:Number = 1;
		public var currentColumn:Number = 0;
		
		public var grid:Array;
		
		
		public function Playlist() 
		{
			addChild(main);
			main.addChild(plMask);
			main.addChild(entries);
			main.addChild(nextBtn);
			main.addChild(prevBtn);
			
			entries.mask = plMask;
			prevBtn.scaleX *= -1;
		}
		
		public function init( content:Array ):void {
			
			pl = content;
			
			var n = setup.playlistThumbNum;
			var tW = setup.playlistThumbWidth;
			var tH = setup.playlistThumbHeight;
			var s = setup.playlistSpacing;
			var p = setup.playlistPadding; 
			
			var cellWidth = (tW + s * 2) + (p) + setup.playlistWidth;
			var cellHeight = (tH + s * 2) + (p);
			
			plWidth = cellWidth;
			plHeight = (cellHeight+s) * n;
			
			plMask.graphics.beginFill(0x000000, 1);
			plMask.graphics.drawRect(-s, -s, plWidth+s, plHeight+s);
			plMask.graphics.endFill();
			
			//var gridCols = cols = Math.round(content.length / n);
			
			for (var j = 1; j < content.length; j++ ) {
				j == n * cols ? cols++ : trace ("columns cal");
				trace ("Columns: " + cols);
			}
			var gridCols = cols;
			
			var gridWidth = ( (tW + p * 2 + s) + (p*4) + setup.playlistWidth )*gridCols;
			var gridHeight = n * (tH + s + (p * 2));
			var gridRows = n;
			
			grid = Grid.create(gridCols, gridRows, cellWidth, cellHeight, p, p, false); 
			
			queue = new LoaderMax( { maxConnections:1, onProgress: queueProgress, onComplete: queueComplete } );
			
			for (var i = 0; i < content.length; i++) {
				trace ("Cover image path: " + content[i].thumbnail);
	
				queue.append( new ImageLoader( content[i].thumbnail, { width: setup.playlistThumbWidth, height: setup.playlistThumbHeight, scaleMode: "proportionalOutside", hAlign: "center", vAlign: "center", crop: true, smoothing: true, centerRegistration:true, onComplete: imageComplete } ));
					
				}
			
			queue.load();
			
			initNavigation();
		}
		
		private function queueProgress(e:LoaderEvent):void {
			trace("Queue progress: " + e.target.progress);
			dispatchEvent(new Event("PlaylistReady"));
			} 
			
		private function queueComplete(e:LoaderEvent):void {
			trace("Queue loading complete.");
			} 
		
		private function imageComplete(e:LoaderEvent):void {
			var img = e.target.content;					// image
			var mask:Sprite = new Sprite();				// image mask
			var bg:Sprite = new Sprite();				// background
			var obj:MovieClip = new MovieClip();		// main object
			
			var tW = setup.playlistThumbWidth;
			var tH = setup.playlistThumbHeight;
			var r = setup.playlistRadius;
			var s = setup.playlistSpacing;
			var p = setup.playlistPadding;
			
			obj.addChild(bg);
				bg.name = "bg";
				bg.alpha = 0.8;
				bg.graphics.lineStyle(1, 0xE2E2E2, 0.4, true);
				bg.graphics.beginFill(0x000000, 0.7);
				bg.graphics.drawRoundRect(0, 0, tW + (p*2) + setup.playlistWidth, tH + (p*2), r+2, r+2);
				bg.graphics.endFill();
				
				var bgGlow = new GlowFilter(0x000000, 0.5, 6, 6, 2);
				bg.filters = [bgGlow];
					
			obj.addChild(mask);
				mask.graphics.beginFill(0x000000, 1);
				mask.graphics.drawRoundRect(p, p, tW, tH, r, r); 
				mask.graphics.endFill();
				
			obj.addChild(img);
				img.name = "img";
				img.x = p + (tW * .5);
				img.y = p + (tH * .5);
			
			var n = entries.numChildren;
				
			obj.n = n;								// progressive number for tracking
			obj.title = pl[n].title;				// title
			obj.description = pl[n].description;	// description
			obj.duration = pl[n].duration;			// duration
			
			var des = createDescription(pl[n].title, pl[n].description);
			obj.addChild(des);
			
			var dur = createDuration(pl[n].duration);
			obj.addChild(dur);
			
			img.mask = mask;
				
			entries.addChild(obj);
			obj.buttonMode = true;
			
			// arrange the grid
			obj.x = grid[n].x;
			obj.y = grid[n].y;
			}

		public function createDescription(title:String, description:String):TextField {
				// the description text field
				var descriptionField:TextField = new TextField();
				
				descriptionField.name = "field";
				descriptionField.autoSize = TextFieldAutoSize.LEFT;
				descriptionField.background = false;
				descriptionField.embedFonts = true;
				descriptionField.border = false;
				descriptionField.selectable = false;
				descriptionField.antiAliasType = AntiAliasType.ADVANCED;
				descriptionField.wordWrap = true;
				descriptionField.multiline = true;
				
				var descriptionFormat:TextFormat = new TextFormat();
				
				descriptionFormat.font = primary.fontName; 
				descriptionFormat.size = setup.playlistTextSize;
				descriptionFormat.letterSpacing = setup.playlistTextKerning;
				descriptionFormat.color = setup.playlistTextColor;
				descriptionFormat.rightMargin = setup.playlistPadding;
				
				descriptionField.defaultTextFormat = descriptionFormat;
				
				descriptionField.width = setup.playlistWidth-setup.playlistPadding;
				descriptionField.height = setup.playlistThumbHeight;
				descriptionField.x = setup.playlistThumbWidth + setup.playlistPadding * 2;
				descriptionField.y = setup.playlistPadding;
				
				var titleContent:String =  "<font size=\"16\">"+title+"</font>" + "\r\n";
				
				descriptionField.htmlText = description;
				
				truncate(descriptionField, setup.playlistTextRows);
				
				descriptionField.htmlText = titleContent + descriptionField.htmlText;
				
				return descriptionField;
			}
			
		function truncate(textfield:TextField, maxLines:int):void
		{
			var alt:String = "...";
		 
			if (textfield.numLines > maxLines)
			{
				var char:int = textfield.getLineOffset(maxLines) - 1;
		 
				char -= alt.length;
				char = textfield.text.substring(0, char + 1).search(/\S\s*$/);
		 
				textfield.htmlText = textfield.text.substring(0, char) + alt;
			}
		}	
		
		public function createDuration(content:String):Sprite {
				var durationField:TextField = new TextField();
				
				durationField.autoSize = TextFieldAutoSize.LEFT;
				durationField.background = false;
				durationField.embedFonts = true;
				durationField.border = false;
				durationField.selectable = false;
				durationField.antiAliasType = AntiAliasType.NORMAL;
				durationField.wordWrap = true;
				durationField.condenseWhite = true;
				
				var durationFormat:TextFormat = new TextFormat();
				
				durationFormat.font = secondary.fontName; 
				durationFormat.size = 8;
				durationFormat.letterSpacing = 0;
				durationFormat.color = 0xFFFFFF;
				durationFormat.rightMargin = 2;
				durationFormat.leftMargin = 2;
				
				durationField.defaultTextFormat = durationFormat;
				
				durationField.text = content;
				
				var duration:Sprite = new Sprite();
				duration.graphics.beginFill(0x000000, 0.6);
				duration.graphics.drawRoundRect(0, 0, durationField.textWidth+6, durationField.height+2, 8, 8);
				duration.graphics.endFill();
				
				duration.addChild(durationField);
				duration.x = setup.playlistThumbWidth - durationField.textWidth - 8 + setup.playlistPadding;
				duration.y = setup.playlistThumbHeight - durationField.height - 4 + setup.playlistPadding;
				
				return duration;
			}
			
		public function arrange(w:Number, h:Number):void {
			
			main.x = Math.floor((w - plWidth) * .5);
			main.y =  Math.floor((h - plHeight) * .5);
			
			nextBtn.x = plWidth + 24;
			prevBtn.x = -24;
			nextBtn.y = prevBtn.y = Math.floor(plHeight * .5);

			}
	
		public function initNavigation():void {
			
			addArrowListeners();
			refreshButtons();
			
			prevBtn.alpha = nextBtn.alpha = 0.7;
		}
			
			
		private function addArrowListeners():void
			{
				nextBtn.buttonMode = true;
				prevBtn.buttonMode = true;
			
				nextBtn.addEventListener(MouseEvent.CLICK, nextClick);
				prevBtn.addEventListener(MouseEvent.CLICK, prevClick);
				
				nextBtn.addEventListener(MouseEvent.MOUSE_OVER, btnOver);
				nextBtn.addEventListener(MouseEvent.MOUSE_OUT, btnOut);
				
				prevBtn.addEventListener(MouseEvent.MOUSE_OVER, btnOver);
				prevBtn.addEventListener(MouseEvent.MOUSE_OUT, btnOut);
			}
			
		private function removeArrowListeners():void
			{
				nextBtn.buttonMode = false;
				prevBtn.buttonMode = false;
			
				nextBtn.removeEventListener(MouseEvent.CLICK, nextClick);
				prevBtn.removeEventListener(MouseEvent.CLICK, prevClick);
				
				nextBtn.removeEventListener(MouseEvent.MOUSE_OVER, btnOver);
				nextBtn.removeEventListener(MouseEvent.MOUSE_OUT, btnOut);
				
				prevBtn.removeEventListener(MouseEvent.MOUSE_OVER, btnOver);
				prevBtn.removeEventListener(MouseEvent.MOUSE_OUT, btnOut);
			}
			
		private function prevClick(e:MouseEvent):void 
			{
				var d = Math.floor((entries.width / cols));
				var s = setup.playlistSpacing;
				
				if (currentColumn > 0) {
					currentColumn--;
					TweenMax.to(entries, 0.5, { x: entries.x + d+s, ease:Cubic.easeInOut, onComplete: addArrowListeners } );
					removeArrowListeners();
				}
				
				refreshButtons();
			}
			
		private function nextClick(e:MouseEvent):void 
			{
				var target = (plWidth - entries.width);
				var d = Math.floor((entries.width / (cols)));
				var s = setup.playlistSpacing;
				
				if (currentColumn < cols-1) {
					currentColumn++;
					removeArrowListeners();
					TweenMax.to(entries, 0.5, { x: entries.x - d -s, ease:Cubic.easeInOut, onComplete: addArrowListeners } );
				}
				
				refreshButtons();
			}
		
		private function btnOver(e:MouseEvent):void {
			TweenMax.to(e.currentTarget, 0.5, { alpha:1 } );
			}
			
		private function btnOut(e:MouseEvent):void {
			TweenMax.to(e.currentTarget, 0.5, { alpha:0.7 } );
			}
			
		private function refreshButtons():void {
				currentColumn == cols-1 ? TweenMax.to(nextBtn.obj, 0.5, { alpha:0.2 }) : TweenMax.to(nextBtn.obj, 0.5, { alpha:1 })
				currentColumn == 0 ? TweenMax.to(prevBtn.obj, 0.5, { alpha:0.2 } ) : TweenMax.to(prevBtn.obj, 0.5, { alpha:1 } );
			}
			
		public function clear():void {
				
				removeArrowListeners();
				
				for (var i = 0; i < entries.numChildren; i++) {
					entries.removeChildAt(0);
					}
				
				main.removeChild(plMask);
				main.removeChild(entries);
				main.removeChild(nextBtn);
				main.removeChild(prevBtn);
			
				entries.mask = null;
				
				removeChild(main);
				
				queue.dispose(true);
			}
	}

}